﻿/*
 * Copyright © 2010 Caduceuscoil. All rights reserved.
 * 
 * This file is part of Search Registry.
 * 
 * RegSearch is open-source software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free Software Foundation,
 * either version 2 of the License, or (at your option) any later version.
 * 
 * RegSearch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with Velodoc XP Edition.
 * If not, see <http://www.gnu.org/licenses/>.
 *  
 */

/* CHANGE LOG
 * Last Modified: 10/22/2010
 * Modified By: CC.
 * -----------------------------------------
 * Initial Version: 10/11/2010
 * Created By: CC.
 * 
 * 
 * BUGS:
 * 
 * 
 * 
 * TODO:
 * 
 */
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace SearchRegistry
{
    /// <summary>
    /// Static class for console colour manipulation.
    /// </summary>
    public static class ConsoleColor
    {
        // constants for console streams
        const int STD_INPUT_HANDLE = -10;
        const int STD_OUTPUT_HANDLE = -11;
        const int STD_ERROR_HANDLE = -12;
        private static COORD ConsoleOutputLocation;
        private static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nStdHandle"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int GetStdHandle(int nStdHandle);

        [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int GetConsoleScreenBufferInfo(int hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

        [DllImport("kernel32.dll", EntryPoint = "SetConsoleTextAttribute", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int SetConsoleTextAttribute(int hConsoleOutput, int wAttributes);
        
        [StructLayout(LayoutKind.Sequential)]
        private struct COORD
        {
            short X;
            short Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct SMALL_RECT
        {
            short Left;
            short Top;
            short Right;
            short Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct CONSOLE_SCREEN_BUFFER_INFO
        {
            public COORD dwSize;
            public COORD dwCursorPosition;
            public int wAttributes;
            public SMALL_RECT srWindow;
            public COORD dwMaximumWindowSize;
        }

        // Colors that can be set
        [Flags]
        public enum Foreground
        {
            Black = 0x0000,
            Blue = 0x0001,
            Green = 0x0002,
            Cyan = 0x0003,
            Red = 0x0004,
            Magenta = 0x0005,
            Yellow = 0x0006,
            Grey = 0x0007,
            White = 0x0008,
            Error = 0x0004 //Red
        }
        
        [Flags]
        public enum Background
        {
            Blue = 0x00000010,
            Green = 0x00000020,
            Cyan = 0x00000030,
            Red = 0x00000040,
            Yellow = 0x00000060,
            Intensity = 0x00000080
        }

        /// <summary>
        /// 
        /// </summary>
        public static void SetConsoleColor()
        {
            //Set console to default color
            SetConsoleColor(Foreground.Grey);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="color"></param>
        public static void SetConsoleColor(Foreground color)
        {
            SetConsoleColor((int)color, 0, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="forcolor"></param>
        /// <param name="backcolor"></param>
        public static void SetConsoleColor(Foreground forcolor,Background backcolor)
        {
            SetConsoleColor((int)forcolor, (int)backcolor, false);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="forcolor"></param>
        /// <param name="backcolor"></param>
        /// <param name="brightColors"></param>
        public static void SetConsoleColor(int forcolor, int backcolor, bool bright)
        {
            int colourMap;
            ConsoleInfo = new CONSOLE_SCREEN_BUFFER_INFO();
            ConsoleOutputLocation = new COORD();

            // get the current console handle
            int hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
            GetConsoleScreenBufferInfo(hConsoleHandle, ref ConsoleInfo);

            // Bright colours OR with white
            if (bright)
                colourMap = forcolor | (int)Foreground.White;
            else
                colourMap = forcolor | backcolor;

            SetConsoleTextAttribute(hConsoleHandle, colourMap);
        }
    }
}